import logging
from apscheduler.schedulers.background import BackgroundScheduler
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.jobstores.memory import MemoryJobStore
from apscheduler.executors.pool import ThreadPoolExecutor, ProcessPoolExecutor
from apscheduler.events import EVENT_JOB_EXECUTED, EVENT_JOB_ERROR
from utils.logger import get_logger

# 创建调度器专用的日志器
logger = get_logger("scheduler", daily_rotation=True)

# 全局调度器实例
_scheduler = None
_scheduler_started = False

class TaskScheduler:
    """任务调度器类，用于统一管理定时任务"""
    
    def __init__(self, scheduler_type='background', timezone='Asia/Shanghai'):
        """初始化任务调度器
        
        Args:
            scheduler_type: 调度器类型，可选值：'background'、'asyncio'，默认为'background'
            timezone: 时区，默认为'Asia/Shanghai'
        """
        # 配置作业存储
        jobstores = {
            'default': MemoryJobStore()
        }
        
        # 配置执行器
        executors = {
            'default': ThreadPoolExecutor(20),
            'processpool': ProcessPoolExecutor(5)
        }
        
        # 作业默认配置
        job_defaults = {
            'coalesce': False,  # 是否合并执行
            'max_instances': 3,  # 最大实例数
            'misfire_grace_time': 60  # 任务错过执行时间的宽限时间（秒）
        }
        
        # 根据类型创建调度器
        if scheduler_type == 'asyncio':
            self.scheduler = AsyncIOScheduler(
                jobstores=jobstores,
                executors=executors,
                job_defaults=job_defaults,
                timezone=timezone
            )
        else:  # 默认使用BackgroundScheduler
            self.scheduler = BackgroundScheduler(
                jobstores=jobstores,
                executors=executors,
                job_defaults=job_defaults,
                timezone=timezone
            )
        
        # 注册事件监听器
        self.scheduler.add_listener(self._job_event_listener, 
                                   EVENT_JOB_EXECUTED | EVENT_JOB_ERROR)
        
        self.is_running = False
    
    def start(self):
        """启动调度器"""
        if not self.is_running:
            self.scheduler.start()
            self.is_running = True
            logger.info("任务调度器已启动")
    
    def shutdown(self, wait=True):
        """关闭调度器
        
        Args:
            wait: 是否等待所有正在运行的任务完成，默认为True
        """
        if self.is_running:
            self.scheduler.shutdown(wait=wait)
            self.is_running = False
            logger.info("任务调度器已关闭")
    
    def add_job(self, func, trigger, **kwargs):
        """添加任务
        
        Args:
            func: 要执行的函数
            trigger: 触发器类型，可以是'date'、'interval'或'cron'
            **kwargs: 其他参数，如id、seconds、minutes等
            
        Returns:
            apscheduler.job.Job: 任务对象
        """
        job = self.scheduler.add_job(func, trigger, **kwargs)
        logger.info(f"已添加任务: {job.id}, 触发器: {trigger}")
        return job
    
    def remove_job(self, job_id):
        """移除任务
        
        Args:
            job_id: 任务ID
        """
        try:
            self.scheduler.remove_job(job_id)
            logger.info(f"已移除任务: {job_id}")
            return True
        except Exception as e:
            logger.error(f"移除任务失败: {job_id}, 错误: {str(e)}")
            return False
    
    def pause_job(self, job_id):
        """暂停任务
        
        Args:
            job_id: 任务ID
        """
        try:
            self.scheduler.pause_job(job_id)
            logger.info(f"已暂停任务: {job_id}")
            return True
        except Exception as e:
            logger.error(f"暂停任务失败: {job_id}, 错误: {str(e)}")
            return False
    
    def resume_job(self, job_id):
        """恢复任务
        
        Args:
            job_id: 任务ID
        """
        try:
            self.scheduler.resume_job(job_id)
            logger.info(f"已恢复任务: {job_id}")
            return True
        except Exception as e:
            logger.error(f"恢复任务失败: {job_id}, 错误: {str(e)}")
            return False
    
    def get_job(self, job_id):
        """获取任务
        
        Args:
            job_id: 任务ID
            
        Returns:
            apscheduler.job.Job: 任务对象
        """
        return self.scheduler.get_job(job_id)
    
    def get_jobs(self):
        """获取所有任务
        
        Returns:
            list: 任务列表
        """
        return self.scheduler.get_jobs()
    
    def _job_event_listener(self, event):
        """任务事件监听器
        
        Args:
            event: 事件对象
        """
        if event.code == EVENT_JOB_EXECUTED:
            logger.debug(f"任务执行成功: {event.job_id}")
        elif event.code == EVENT_JOB_ERROR:
            logger.error(f"任务执行失败: {event.job_id}, 错误: {str(event.exception)}")


def get_scheduler(scheduler_type='background', timezone='Asia/Shanghai'):
    """获取全局调度器实例
    
    Args:
        scheduler_type: 调度器类型，可选值：'background'、'asyncio'，默认为'background'
        timezone: 时区，默认为'Asia/Shanghai'
        
    Returns:
        TaskScheduler: 调度器实例
    """
    global _scheduler, _scheduler_started
    
    # 如果调度器已经创建，直接返回
    if _scheduler is not None:
        return _scheduler
    
    # 创建新的调度器实例
    _scheduler = TaskScheduler(scheduler_type=scheduler_type, timezone=timezone)
    
    # 如果调度器尚未启动，则启动它
    if not _scheduler_started:
        _scheduler.start()
        _scheduler_started = True
    
    return _scheduler


def shutdown_scheduler(wait=True):
    """关闭全局调度器
    
    Args:
        wait: 是否等待所有正在运行的任务完成，默认为True
    """
    global _scheduler, _scheduler_started
    
    if _scheduler is not None and _scheduler_started:
        _scheduler.shutdown(wait=wait)
        _scheduler_started = False
        logger.info("全局调度器已关闭")
        
        # 重置调度器实例，以便下次重新创建
        _scheduler = None